create or replace package m4o_v2 as

  subtype t  is varchar2(32767);

  type map_t is table of t index by t;

  type tbl_t is table of varchar2(32767) index by binary_integer;

  CR constant varchar2(1) := chr(10);
  WS constant varchar2(4) := ' '||chr(9)||CR||chr(13);

  -- ===========================================================================
  -- Convert
  --   'foo:bar:baz'
  -- to (with i_separator=':')
  --   m4o_v2tab('foo','bar','baz')
  function split(
    i_str       in varchar2,
    i_separator in varchar2 := ',')
  return m4o_v2tab;
  -- ===========================================================================
  -- Convert
  --   'foo:bar:baz'
  -- to (with i_separator=':')
  --   m4o_v2tab('foo','bar','baz')
  function split_clob(
    i_clob      in clob,
    i_separator in varchar2 := ',')
  return m4o_v2tab;
  -- ===========================================================================
  -- Convert
  --   'foo=1:bar=2:baz=3'
  -- to (with i_separator=':' and i_val_sep='=')
  --   m4o_v2.map_t(foo => 1, bar => 2, baz => 3)
  function mapsplit(
    i_str       in varchar2,
    i_separator in varchar2 := ',',
    i_val_sep   in varchar2 := '=' )
  return map_t;
  -- ===========================================================================
  -- Convert
  --   m4o_v2tab('foo','bar','baz')
  -- to (with i_glue=':')
  --   'foo:bar:baz'
  function join(
    i_tbl  in m4o_v2tab,
    i_glue in varchar2 := ',')
  return varchar2;
  -- ===========================================================================
  -- return hits \1 to \9 of the regular expression i_regexp in i_str
  function regexp_matches(
    i_str    in varchar2,
    i_regexp in varchar2)
  return m4o_v2tab;
  -- ===========================================================================
  -- append i_elem to i_dest
  procedure push(
    i_dest in out nocopy m4o_v2tab,
    i_elem in varchar2);
  -- ===========================================================================
  -- append i_elem to i_dest, separate them with i_glue if i_dest is not empty
  procedure push(
    i_dest in out nocopy varchar2,
    i_elem in varchar2,
    i_glue in varchar2 := ',');
  -- ===========================================================================
  -- append i_elem to i_dest, separate them with i_glue if i_dest is not empty
  procedure push(
    i_dest in out nocopy clob,
    i_elem in varchar2,
    i_glue in varchar2 := ',');
  -- ===========================================================================
  -- ltrim and rtrim WS from i_str
  function trim_ws(i_str in varchar2)
  return varchar2;
end;
/
